<template>
  <div class="StatisticDetail">
    <!-- <Common-View
      ref="common-view"
      class="common-view"
      :auto-get-data="false"
      :just-look="step === 0 || dbLock "
    /> -->
    <Fab-Btn
      :show="isFabBtnShow"
      @btnClick="fabBtnClick"
    />
    <Common-View
      ref="common-view"
      class="common-view"
      :auto-get-data="false"
      :just-look="step === 0 || dbLock "
      :insert-index-last="insertIndexLast"
    >
      <template v-if="isDb || isCommenOpen" #myBottom>
        <div v-if="isDb" style="position: relative; z-index: 9;">
          <div
            v-if="step === 0 || loading"
            :class="{
              'mybtn': 1,
              'normal': 1,
              'fixedBottom': 1,
              'loading': loading,
              'disabled': loading || disabled
            }"

            @click="nextStep"
          >
            <div
              v-if="!loading && isCommenOpen && isDb && step === 0"
              class="comment-btn"
            >
              <div class="split-line">
                <u-icon class="btn-icon" name="play-right-fill" color="#17BE50" size="38" />
                <span>下一步</span>
              </div>
              <div @click.stop="openComment">
                <u-icon class="btn-icon" name="chat-fill" color="#1792FF" size="38" />
                <span>评论</span>
              </div>
            </div>
            <span v-else>
              {{ loading ? '载入中..' : step ? '提交' : '下一步' }}
            </span>
          </div>

          <div
            v-else
            class="bottom-fix"
          >

            <div :class="{'border-right': myDbType !== '1'}" @click="back">
              上一步
            </div>
            <div v-if="prevNode && myDbType !== '1'" @click="submitDB('reject')">
              <div>驳回</div>
            </div>
            <div v-if="myDbType !== '1'" class="border-left" @click="submitDB('agree')">
              {{
                submitBtnLabel
              }}
            </div>
          </div>
        </div>

        <div v-if="!isDb && isCommenOpen" class="comment-btn ">
          <div class="my-center comment-btn-bg" @click.stop="openComment">
            <u-icon class="btn-icon" name="chat-fill" color="#1792FF" size="38" />
            <span>评论</span>
          </div>
        </div>
      </template>

      <template v-else #myBottom>
        <div />
      </template>

    </Common-View>

    <div v-show="isCommenOpen && step === 0" class="Statistic-comment safeHeight">
      <!-- 这是评论 -->
      <TaskCells
        :list="commentList"
        @recallComment="commentWithdraw"
      />
      <div v-show="commentList.length === 1" class="no-comment">
        暂无评论
      </div>
    </div>

    <div v-if="step === 1" class="time-line safeHeight">
      <My-Time-Line
        :list="bpmProcessLog"
      />
    </div>

    <u-popup v-model="commentInpusVisible" mode="top">
      <div style="height: 100vh;padding-top: 10px;">
        <Comment-Input
          ref="commentRef"
          :input-call-back="addCommentValue"
          placeholder="请输入"
          submit-text="确认"
          :inpit-height="350"
          emit-close
          @close="commentInpusVisible = false"
        />
      </div>
    </u-popup>

  </div>
</template>

<script>
/* eslint-disable no-undef */
import FabBtn from 'pages/statistic/FabBtn';
import CommonView from 'pages/CommomList/CommonView';
import MyTimeLine from 'components/timeLine/MyTimeLine';
import CommentInput from 'common/commentInput/CommentInput';
import TaskCells from '@/pages/TaskDetail/components/taskInfo/components/TaskCells';

import { mapState } from 'vuex';
import { getLocalStorage, Message } from '@/utils/utils';
import { getUserAvatar } from '@/pages/TaskDetail/common';
import { getImgUrl } from '@/utils/files';

import {
  uploadFilesArr,
  isPromise,
  getServerFiles,
  getModelStyleData,
  filterIsForm,
  collectCopyRow
} from '@/pages/statistic/commonMethods.js';
import {
  updCommentStatus,
  handleNodeFreeSelectUser,
  getInstanceOpinion
} from '@/api/commonlist';

import _ from 'lodash';
// _.cloneDeep(this.$route.query);

import {
  queryHeaderByTableId,
  submitApprove, // 提交
  // flowImageInfo,
  listComment,
  addComment,
  getCanBackHistoryNodes
} from '@/api/commonlist';

export default {
  name: 'StatisticDetail',

  components: {
    CommonView,
    MyTimeLine,
    CommentInput,
    TaskCells,
    FabBtn
  },

  data() {
    return {
      myType: '',
      myTypmyDbTypee: '', // ‘1’ 我的已办
      spTableId: '',
      defId: '',
      defKey: '',
      taskId: '',
      instId: '',
      sId: '',
      formGuid: '',
      isComment: '0',

      step: 0,
      loading: false,
      disabled: false,
      dbLock: false,

      prevNode: '',
      nextNode: '',

      renderData: [],
      spRenderData: [],

      // 评论
      commentUserAvatar: {}, // userId -> avatar
      commentInpusVisible: false,
      commentList: [],
      bpmProcessLog: [], // 流程日志

      // 是否可以复制行
      isModelForm: false, // 模板
      isApproveForm: false, // 审批
      copyModelHeaders: [],
      copyApproveHeaders: [],
      copyModelIndex: 1,
      copyApproveIndex: 1,
      insertIndexLast: -1

    };
  },

  computed: {
    ...mapState('formModule', ['componentType']),

    // 是否处于我的待办
    isDb() {
      return this.myType === 'myDb';
    },

    // 是否评论
    isCommenOpen() {
      return this.isComment === '1';
    },

    // 通过按钮显示的label
    submitBtnLabel() {
      const dbLock = this.dbLock; // body是否有数据
      const prevNode = this.prevNode;
      if (dbLock && (!prevNode)) {
        return '重新提交';
      } else if (dbLock) {
        return '通过';
      } else {
        return '提交';
      }
    },

    // 是否显示复制行按钮
    isFabBtnShow() {
      const step = this.step;
      if (this.locked || this.dbLock) {
        return false;
      }

      if (step === 0) {
        return this.isModelForm;
      } else {
        return this.isApproveForm;
      }
    }

  },

  mounted() {
    this.init();
  },

  methods: {
    async init() {
      const {
        formGuid,
        tableIds,
        modelName, // 模板名称

        myType, // 可能存在值 "myDb" （我的待办）
        spTableId, // 我的待办时候存在， 审批内容id
        defId, // 我的待办时候存在
        defKey, // 我的待办时候存在
        instId, // 我的待办时候存在
        isComment, // 我的待办时候存在  是否评论
        taskId, // 我的待办时候存在
        sId, // 我的待办时候存在
        myDbType
      } = this.$route.query;

      this.myType = myType;
      this.myDbType = myDbType;
      this.spTableId = spTableId;
      this.defId = defId;
      this.sId = sId;
      this.defKey = defKey;
      this.instId = instId;
      this.taskId = taskId;
      this.formGuid = formGuid;
      this.isComment = isComment + '';
      this.loading = true;
      const subscriber = [];

      this.clear();

      if (instId || taskId) {
        subscriber.push(
          this.getProcessLog({ instId, taskId })
        );
      }

      const myAvatar = getLocalStorage('userAvatar');
      const userId = getLocalStorage('userId');

      if (myAvatar) {
        this.commentUserAvatar[userId] = myAvatar;
      }

      if (this.isDb) {
        // this.getFlowNode({ defId, instId });
      }

      if (this.isCommenOpen) {
        this.getComment({ taskGuid: formGuid });
      }

      await getModelStyleData(modelName).then(res => {
        if (res) {
          const {
            isApproveForm,
            isModelForm
          } = res;

          this.isModelForm = isModelForm;
          this.isApproveForm = isApproveForm;
        }
      });

      if (tableIds) {
        const tableIdsArr = (tableIds + '').split(',');
        // 我发起点进来不需要看审批内容
        if (myType === '我发起') {
          tableIdsArr.length = 1;
        }

        const fileFormGuid = formGuid;

        tableIdsArr.map(tableId => {
          subscriber.push(
            this.getData({
              tableId,
              formGuid
            }).then(res => {
              getServerFiles(this.renderData, fileFormGuid, this.componentType);
              this.upDataView(this.renderData);
              return Promise.resolve(res);
            })
          );
        });
      }

      Promise.all(subscriber).then(() => {
        setTimeout(() => {
          this.loading = false;
        }, 500);
      });
    },

    fabBtnClick() {
      const {
        step,
        renderData,
        spRenderData,

        copyModelHeaders: copyModelHeaders1,
        copyApproveHeaders: copyApproveHeaders1,

        upDataView
      } = this;
      const copyModelHeaders = _.cloneDeep(copyModelHeaders1);
      const copyApproveHeaders = _.cloneDeep(copyApproveHeaders1);

      let [rData, cData] = [null, null];
      let flag = true;

      // 审批界面
      if (step) {
        if (copyApproveHeaders.length) {
          rData = spRenderData;
          cData = copyApproveHeaders;
        } else {
          Message('审批内容可复制的行为空');
          flag = false;
        }
      } else {
        // 模板界面
        if (copyModelHeaders.length) {
          rData = renderData;
          cData = copyModelHeaders;
        } else {
          Message('模板内容可复制的行为空');
          flag = false;
        }
      }

      if (flag) {
        const myCopyIndex = this.copyApproveIndex++;
        cData.forEach(item => {
          // 标记行号(提交用到)
          item.myCopyIndex = myCopyIndex;
          item.myValue = '';
        });

        const orders = rData.map(o => o.orderId);
        const insertMaxOrderId = Math.max(...cData.map(o => o.orderId));

        const insertIndex = orders.lastIndexOf(insertMaxOrderId) + 1;
        this.insertIndexLast = insertIndex;
        rData.splice(insertIndex, 0, ...cData);
        upDataView(rData);

        // 页面滚动
        this.$nextTick(() => {
          const el = document.querySelector('.CommonInstance_instanceAddLast');
          window.scrollTo({
            top: el.offsetTop,
            behavior: 'smooth'
          });
        });
      }
    },

    getNearLyBpm() {
      const {
        taskId,
        bpmProcessLog
      } = this;
      const subscriber = [];
      const action = 'agree';
      const len = bpmProcessLog.length;
      const instanceNow = bpmProcessLog[len - 1];
      const {
        taskKey: nodeId // UserTask2 (nodeId)
      } = instanceNow;
      const requestData = {
        action,
        nodeId,
        taskId,
        'data': {},
        'extendConf': { 'nodeId': '' }
      };

      const isCanBack = getCanBackHistoryNodes({ taskId }).then(res => {
        const { data } = res;
        if (data) {
          const arr = Object.keys(data);
          this.prevNode = arr[arr.length - 1];
        }
        return Promise.resolve(res);
      });

      const isNext = handleNodeFreeSelectUser(requestData).then(res => {
        const { success, data } = res;
        if (success) {
          const { nodeIdentitysMap } = data;
          this.nextNode = nodeIdentitysMap;
        }
        return Promise.resolve(res);
      });
      subscriber.push(
        isCanBack,
        isNext
      );

      return Promise.all(subscriber);
    },

    // 撤回评论
    commentWithdraw(v) {
      const {
        item: {
          guid
        },
        index
      } = v;
      updCommentStatus({
        status: -1,
        guid
      }).then(res => {
        if (res.success) {
          this.commentList.splice(index, 1);
        }
      });
    },

    // 添加评论
    addCommentValue(value) {
      const {
        formGuid: taskGuid
      } = this;
      const {
        content,
        files
      } = value;

      const formData = new FormData();
      formData.append('taskGuid', taskGuid.split('_')[0]);
      formData.append('content', content);
      formData.append('type', 'Y0012');
      formData.append('editUser', getLocalStorage('userId'));
      formData.append('enterpriseCode', taskGuid);

      files.map(({ file }) => {
        formData.append('files', file);
      });

      uni.showLoading({
        title: '提交中...'
      });

      addComment(formData).then(res => {
        const {
          success,
          message
        } = res;
        uni.hideLoading();

        setTimeout(() => {
          Message(message);
        }, 500);

        if (success) {
          this.closeComment();
          this.commentList = [
            {
              groupTitle: '评论区'
            }
          ];

          this.getComment({
            taskGuid: this.formGuid
          });
        }
      });
    },

    openComment() {
      this.commentInpusVisible = true;
    },

    closeComment() {
      this.commentInpusVisible = false;
    },

    // 获取评论
    getComment({ taskGuid }) {
      taskGuid = taskGuid.split('_')[0];
      listComment({ taskGuid }).then(async(res) => {
        const {
          success,
          data
        } = res;

        if (success) {
          for (let i = 0; i < data.length; i++) {
            const item = data[i];
            const {
              avatar,
              avatarId,
              content,
              editTime,
              editUser,
              trueName,
              annexIds
            } = item;

            const subscriber = [];

            Object.assign(item, {
              contentType: 2,
              cardMsg: {
                content,
                avatar: '',
                photolist: [],
                time: editTime,
                name: trueName,
                isHideBackWord: getLocalStorage('userId') + '' !== editUser
              }
            });

            if (avatar && avatarId) {
              const { commentUserAvatar } = this;
              const avatar1 = commentUserAvatar[editUser];

              if (avatar1) {
                item.cardMsg.avatar = avatar1;
              } else {
                getUserAvatar({
                  avatar: avatarId,
                  avatarId: avatar,
                  userId: editUser
                }).then(res => {
                  commentUserAvatar[editUser] = res;
                  item.cardMsg.avatar = res;
                });
              }
            }

            if (annexIds && annexIds.length) {
              for (let j = 0; j < annexIds.length; j++) {
                const fileInfo = annexIds[j];
                const {
                  id,
                  originName: fileName
                } = fileInfo;

                getImgUrl({
                  id, fileName
                }).then(url => {
                  item.cardMsg.photolist.push({
                    ...fileInfo,
                    img: url
                  });
                });
              }
            }
            await Promise.all(subscriber);
            this.commentList.push(item);
          }
        }
      });
    },

    getFlowNode(data) {
      // flowImageInfo(data).then(res => {
      //   if (res.success) {
      //     const data = res.data;
      //     const { flowElements } = data;
      //   }
      // });
    },

    upDataView(data) {
      this.$refs['common-view'].setData(data);
    },

    // 提交待办
    async submitDB(action) {
      const {
        instId,
        taskId,
        sId,
        formGuid,
        bpmProcessLog,
        spTableId: tableId,
        spRenderData,
        dbLock,
        defId,
        defKey,

        prevNode,
        nextNode,

        componentType
      } = this;
      const len = bpmProcessLog.length;
      const opinion = action === 'agree' ? '同意' : '驳回';

      if (len) {
        const instanceNow = bpmProcessLog[len - 1];
        let needUploadFiles = false;

        const {
          taskKey: nodeId // UserTask2 (nodeId)
        } = instanceNow;
        const fileTypes = Object.values(componentType);

        const requestData1 = {
          formGuid,
          bodyData: (dbLock || opinion === '驳回') ? [{}] : [
            {
              tableId,
              data: [
                spRenderData.reduce((p, c) => {
                  if (fileTypes.includes(c.componentType)) {
                    needUploadFiles = true;
                  } else {
                    if (!c.myCopyIndex) {
                      p[c.dataIndex] = c.myValue;
                    }
                  }
                  return p;
                }, {})
              ]
            }
          ],

          bpmBody: {
            action,
            // destination: Object.keys(nodeIdentitysMap)[0],
            defId,
            opinion,
            taskId,
            instanceId: instId,
            extendConf: { nodeId: '' },
            // nodeUsers: nodeIdentitysMap,
            defKey,
            sId,
            formGuid
          }
        };

        // 不是发起节点
        if (nodeId.startsWith('User')) {
          if (opinion === '驳回') {
            if (prevNode) {
              Object.assign(requestData1.bpmBody, {
                destination: prevNode,
                nodeUsers: { [prevNode]: '' }
              });
            }
          } else {
            // 通过
            const flag1 = nextNode instanceof Object;
            const flag = flag1 && Object.keys(nextNode).length || false;
            if (flag) {
              // submitApprove
              this.loading = true;
              Object.assign(requestData1.bpmBody, {
                destination: Object.keys(nextNode)[0],
                nodeUsers: nextNode
              });
            }

            // await handleNodeFreeSelectUser(requestData).then(res => {
            //   const { success, data } = res;
            //   if (success) {
            //     const { nodeIdentitysMap } = data;
            //     const flag1 = nodeIdentitysMap instanceof Object;
            //     const flag = flag1 && Object.keys(nodeIdentitysMap).length || false;

            //     // ? TODO: 目前逻辑是流程只能是一条线走下去没有分支
            //     if (flag) {
            //       // submitApprove
            //       this.loading = true;
            //       Object.assign(requestData1.bpmBody, {
            //         destination: Object.keys(nodeIdentitysMap)[0],
            //         nodeUsers: nodeIdentitysMap
            //       });
            //     }
            //   }
            // });
          }

          const copyValues = collectCopyRow(this.spRenderData).map(row => {
            return row.reduce((p, c) => {
              p[c.dataIndex] = c.myValue;
              return p;
            }, {});
          });

          requestData1.bodyData[0].data.push(...copyValues);

          submitApprove(requestData1).then(res => {
            const { success, message } = res;
            if (success) {
              if (needUploadFiles) {
                // 有文件待提交
                const filesItem = spRenderData.filter(item => item.componentType === componentType.chooseFile);
                const imgsItem = spRenderData.filter(item => item.componentType === componentType.chooseImage);

                const waitPrimise = uploadFilesArr({
                  filesItem,
                  imgsItem,
                  guid: formGuid
                });

                if (isPromise(waitPrimise)) {
                  waitPrimise.then(() => {
                    this.subSuccessLeave(message);
                  });
                } else {
                  this.subSuccessLeave(message);
                }
              } else {
                this.subSuccessLeave(message);
              }
            }
          });
        }
      }

      setTimeout(() => {
        this.loading = false;
      }, 500);
    },

    // 提交成功后离开
    subSuccessLeave(message) {
      Message(message);
      setTimeout(() => {
        this.$router.replace({
          path: '/StatisticCenterList'
        });
      }, 500);
    },

    // 获取流程日志
    getProcessLog({ instId, taskId }) {
      return new Promise((r, j) => {
        getInstanceOpinion({ instId, taskId }).then(res => {
          const {
            success,
            message,
            data
          } = res;

          if (success) {
            this.bpmProcessLog = data;
            r(data);
          } else {
            j(message);
          }
        });
      });
    },

    async nextStep(n) {
      // this.step = this.step ? 0 : 1;
      if (typeof n === 'number') {
        this.step = n;
      }

      if (this.step > 0) {
        return this.submitDB();
      } else {
        if (typeof n !== 'number') {
          this.step = 1;
        }
        const {
          step,
          spRenderData,
          spTableId,
          formGuid,
          myDbType,

          prevNode,
          nextNode
        } = this;

        if (step) {
          const data = spRenderData;
          this.loading = true;

          if ((!nextNode || !prevNode) && myDbType !== '1') {
            await this.getNearLyBpm();
          }

          this.loading = false;
          if (data.length) {
            this.upDataView(data);
          } else {
            this.loading = true;
            this.getData(
              {
                tableId: spTableId,
                formGuid
              }, 'notAssign'
            ).then(async({ success, data }) => {
              setTimeout(() => {
                this.loading = false;
              }, 500);
              if (success) {
                const { headers: headers1, bodys } = data;
                let locked = false;

                if (bodys.length) {
                  const [row, ...restBodys] = bodys;
                  const { copy } = filterIsForm(headers1, this.isApproveForm);

                  locked = true;

                  headers1.forEach(item => {
                    const { dataIndex } = item;

                    if (dataIndex in row) {
                      item.myValue = row[dataIndex];
                    }
                  });
                  restBodys.forEach(row => {
                    // const item = copy.find(o => o.dataIndex === )
                    for (const key in row) {
                      const item = copy.find(o => o.dataIndex === key);
                      if (item) {
                        const i_item = _.cloneDeep(item);
                        i_item.myValue = row[key];
                        headers1.push(i_item);
                      }
                    }
                  });
                }

                let headers = [];
                if (this.isApproveForm) {
                  const filterHeader = filterIsForm(headers1, this.isApproveForm);
                  if (bodys.length) {
                    headers = headers1;
                  } else {
                    headers = filterHeader.headers;
                  }
                  this.copyApproveHeaders = filterHeader.copy;
                } else {
                  headers = headers1;
                }

                getServerFiles(headers, formGuid, this.componentType).then((values) => {
                  const didLocked = values.some(o => {
                    const v = o.value.data;
                    if (Array.isArray(v)) {
                      return v.length;
                    } else {
                      return v;
                    }
                  });
                  !locked && (locked = didLocked);
                  this.dbLock = locked;
                  this.upDataView(headers);

                  this.spRenderData = headers;
                });
              }
            });
          }
        } else {
          this.upDataView(this.renderData);
        }
      }
    },

    clear() {
      this.renderData = [];
      this.spRenderData = [];
      this.commentList = [
        {
          groupTitle: '评论区'
        }
      ];
    },

    back() {
      this.nextStep(0);
    },

    getData({ tableId, formGuid }, type) {
      return queryHeaderByTableId({ tableId, formGuid }).then(res => {
        if (res.success) {
          const {
            bodys,
            headers: headers1
          } = res.data;

          const row = bodys && bodys[0] || {};
          headers1.sort((a, b) => a.orderId - b.orderId);
          const headers2 = headers1.filter(item => item.status !== 1);
          headers2.forEach(item => {
            const dataIndex = item.dataIndex;

            item.myValue = item.defaultValue;
            if (dataIndex in row) {
              item.myValue = row[dataIndex];
            }
          });
          if (type !== 'notAssign') {
            let headers = [];
            if (this.isModelForm) {
              const filterHeader = filterIsForm(headers2);
              headers = filterHeader.headers;
              this.copyModelHeaders = filterHeader.copy;
            } else {
              headers = headers2;
            }

            this.renderData = headers;
          }
        }

        return Promise.resolve(res);
      });
    }
  }

};
</script>

<style lang="scss" scoped>
.StatisticDetail {
  width: 100%;
  height: 100%;

  .common-view {
    position: relative;
    z-index: 10;
  }

  .safeHeight {
    &::after {
      content: '';
      display: block;
      width: 100%;
      height: 44px;
    }
  }

  .bottom-fix {
    color: #fff;
    position: fixed;
    display: block;
    margin-left: auto;
    margin-right: auto;
    // padding-left: 14px;
    // padding-right: 14px;
    box-sizing: border-box;
    font-size: 18px;
    text-align: center;
    text-decoration: none;
    line-height: 2.55555556;
    -webkit-tap-highlight-color: transparent;
    overflow: hidden;
    cursor: pointer;

    left: 0;
    right: 0;
    bottom: 0;

    display: flex;
    > div {
      flex: 1;
      height: 100%;
      width: 100%;
      background-color: #007AFF;
    }

    .border-left {
      border-left: 1px solid #fff;
    }

    .border-right {
      border-right: 1px solid #fff;

    }
  }

  .time-line {
    margin-top: 30px;
    padding: 10px 25px;
    background-color: #fff;
  }

  .Statistic-comment {
    margin-top: 30px;
  }

  .comment-btn {
    background-color: #fff;
    color: #333333;
    position: fixed;
    right: 0;
    left: 0;
    bottom: 0;
    height: 45px;
    border-top: 1px solid #EDEEF2;
    z-index: 9;

    display: flex;
    align-items: center;

    > div {
      flex: 1;
    }

    .btn-icon {
      margin-right: 5px;
    }

    .split-line {
      &::after {
        content: '';
        display: inline-block;
        width: 1px;
        height: 20px;
        background-color: #E1E1E1;
        position: absolute;
        z-index: 3;
        right: 50%;
        bottom: 13px;
      }
    }

  }

  .my-center {
    justify-content: center;
    margin: 0 auto;
    text-align: center;
  }

}

.comment-btn-bg {
    height: 45px;
    background-color: #fff;
    display: flex;
    align-items: center;
    border-top: 1px solid #ebedf0;
}

.no-comment {
  background-color: #fff;
  padding: 10px 12px;
  font-size: 14px;
  color: #333;
}

</style>
